/*---------------------------------------------------------------------
 * File name: simple_buffer.h
 *
 * Copyright (c) <2020-2022>, <ChenLong>
 *
 * All rights reserved.
 *
 * Author: ChenLong
 * Email: worldlong@foxmail.com
 *--------------------------------------------------------------------*/
#pragma once

#include <cstring>
/*
*/
template<typename Type>
class SimpleBuffer
{
public:
  SimpleBuffer(Type *buffer, int size) :
    _buffer(buffer),
    _size(size),
    _number(0),
    _push_index(0),
    _pop_index(0)
  {}
  
  int number() {
    return _number;
  }
  
  int size() {
    return _size;
  }
  
  bool full_check(int number) {
    if(number + _number > _size) {
      return true;
    }
    return false;
  }
  
  //push
  int push(Type *data, int number)
  {
    if(number > _size) {
      number = _size;
    }
    
    int residual = _size - _push_index;
    if(number + _number > _size) { //just reset
      _number = 0;
      _push_index = 0;
      _pop_index = 0;
    } else if(number > residual) { //move to head of _buffer
      memcpy(_buffer, _buffer + _pop_index, _number * sizeof(Type));
      _push_index = _number;
      _pop_index = 0;
    }
  
    memcpy(_buffer + _push_index, data, number * sizeof(Type));
    _push_index += number;
    _number += number;
    return number;
  }
  //pop
  int pop(Type *data, int number)
  {
    if(_number == 0) {
      return 0;
    } else if(_number < number) {
      number = _number;
    }
    
    /* _pop_index will be always <= _push_index */
    memcpy(data, _buffer + _pop_index, number * sizeof(Type));
    _pop_index += number;
    _number -= number;
    
    return number;
  }
  
  //flush
  void flush()
  {
    _number = 0;
    _push_index = 0;
    _pop_index = 0;
  }
private:
  Type *_buffer;
  int _size;
  int _number;
  int _push_index;
  int _pop_index;
};




